const net = require('net');
const Frame = require("./net/Frame");
const log4js = require("log4js");
const Log = log4js.getLogger("server");


/**
 * Server 就是一个 socket 服务器
 * 接收普通连接，将内容原封不动的发给 proxy
 * 响应 Proxy 返回的（Master 转发的）报文，操作对应的真实 Client。
 */

class Server {
    constructor(proxyframe, port){
        // 真实 clients 的集合
        this.clients = {}
        this.proxy = proxyframe;
        this.port = port;
    }

    destroy(){
        Log.debug("Server destroy on" + this.port)
        if( this.server ){
            this.server.close()
        }
    }

    /**
     * 将消息分发给真正的客户端
     * @param msg
     */
    distribute(msg){
        Log.debug("distribute data to " + msg.client)
        let client = this.clients[msg.client];
        if( client ){
            client.write( new Buffer(msg.origin.data) );
        }
    }


    /**
     * 控制连接
     * @param msg
     */
    control(msg){
        Log.debug("control " + msg.client)
        let client = this.clients[msg.client];
        if( client ){
            client.destroy()
            delete this.clients[msg.client]
        }
    }

    async start(){
        return new Promise( (ok, err) => {
            this.server = net.createServer((sock) => {
                let client = sock.remoteAddress + ' ' + sock.remotePort;

                Log.debug('Client CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);

                this.proxy.send({
                    cmd : "new",
                    data : {
                        client : client
                    }
                })

                this.clients[client] = sock

                sock.on('data', (data) => {
                    this.proxy.send({
                        cmd : "data",
                        data : {
                            client : client,
                            origin : data
                        }
                    })
                });

                sock.on('close', (data) => {
                    this.proxy.send({
                        cmd : "delete",
                        data : {
                            client : client
                        }
                    })
                });

                sock.on('error', (data) => {
                });

            })

            this.server.on("error", function (e) {
                err(e)
            })


            this.server.listen(this.port, () => {
                Log.info('Server listening on 0.0.0.0:' + this.port);
                ok(this.port)
            });
        })
    }
}


module.exports = Server;